using System;
using System.IO;
using System.Threading;

namespace PaulRz.Util.Threading.ThreadedLogger
{
    /// <summary>
    /// Rewritten FUtil.log functions without semantic changes
    /// </summary>
    public static class FUtilLog
    {
        private static TextWriter logWriter = null;
        private static Logger logger = null;

        private static string logDirectory = null;
        private static string appName = null;

        private static DateTime timeLogCreation; // the date-time of last log's creation

        /// <summary>
        /// Stops and Dispose the underlying logger
        /// </summary>
        public static void Stop()
        {
            if (logger != null)
            {
                logger.Stop();
                logger = null;
            }
        }

        /// <summary>
        /// Default logger for Dispatcher
        /// </summary>
        /// <param name="msg"></param>
        public static void log(string msg)
        {
            log(msg, "", "Dispatcher");
        }

        /// <summary>
        /// Arranges and logs the msg.
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="logPathDirectory"></param>
        /// <param name="name"></param>
        public static void log(string msg, string logPathDirectory, string name)
        {
            if (logWriter == null)
            {
                logDirectory = logPathDirectory;
                appName = name;
                logWriter = createLogStream(logPathDirectory, name);
            }

            string message;

            if (msg != null)
                message = arrangeLogRecord(msg);
            else
                message = arrangeLogRecord("null message!");

            logger.LogString(message);
        }

        /// <summary>
        /// Format the string in the form of "DateTime #ThreadId message"
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        public static string arrangeLogRecord(string message)
        {
            return
                string.Format("{0} #{2}	{1}", DateTime.Now.ToString(FormatProvider.CRM), message,
                              Thread.CurrentThread.ManagedThreadId);
        }

        private static TextWriter createLogStream(string logDirectoryPath, string name)
        {
            TextWriter logStreamWriter;
            timeLogCreation = DateTime.Now;
            if (String.IsNullOrEmpty(logDirectoryPath))
            {
                logStreamWriter =
                    new StreamWriter(
                        FUtil.getConfigPath(timeLogCreation.ToString("ddMMyyyyHHmmss") + "-" + name + ".log"), true);
            }
            else
            {
                DirectoryInfo info = new DirectoryInfo(FUtil.getConfigPath(logDirectoryPath));
                if (!info.Exists)
                    info.Create();

                logStreamWriter =
                    new StreamWriter(
                        FUtil.getConfigPath(logDirectoryPath + "\\" + timeLogCreation.ToString("ddMMyyyyHHmmss") + "-" +
                                            name + ".log"), true);
            }

            if (logger == null)
            {
                logger = new Logger(logStreamWriter, 300, 1000);
                logger.OnLogRotate += new LogRotate(logger_OnLogRotate);
                logger.Start();
            }
            else
            {
                logger.ChangeWriter(logStreamWriter);
                logger.LogString(arrangeLogRecord("New log created due to day change!"));
            }

            return logStreamWriter;
        }

        private static void logger_OnLogRotate(Logger sender)
        {
            DateTime now = DateTime.Now;
            if (timeLogCreation.Day != now.Day)
            {
                timeLogCreation = now;
                logWriter = createLogStream(logDirectory, appName);
            }
        }
    }
}